package com.africanmoviesmobile.ui;

import java.io.IOException;
import java.util.Vector;

import org.pixmob.httpclient.HttpClientException;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.RelativeLayout;

import com.africanmoviesmobile.R;
import com.africanmoviesmobile.fragment.LatestMoviesFragment;
import com.africanmoviesmobile.util.bitmap.ImageCache.ImageCacheParams;
import com.africanmoviesmobile.util.bitmap.ImageFetcher;
import com.africanmoviesmobile.webservice.AmmWebService;
import com.africanmoviesmobile.webservice.BasicAsyncCallback;
import com.africanmoviesmobile.webservice.WebServiceException;
import com.africanmoviesmobile.webservice.inf.Movie;
import com.africanmoviesmobile.webservice.inf.WebserviceObject;
import com.devsmart.android.ui.HorizontalListView;
import com.viewpagerindicator.CirclePageIndicator;
import com.viewpagerindicator.PageIndicator;

public class HomeActivity extends BaseActivity implements OnClickListener, OnItemClickListener {
	
	private LayoutInflater mLayoutInflater;
	private ViewPager mLatestMoviesPager;
	private PageIndicator mLatestMoviesPageIndicator;
	
	ImageFetcher mLatestMoviesCoverFetcher;
	ImageFetcher mLatestMoviesScreenshotFetcher;
	ImageFetcher mTopRatedMoviesCoverFetcher;
	
	AmmWebService mAmmWebService;
	
	private LatestMoviesAdapter mLatestMoviesAdapter;
	private TopRatedMoviesAdapter mTopRatedMoviesAdapter;
	private ViewPagerTimeThread mViewPagerTimeThread;
	
	private int mLatestMoviesViewPagerCount = -1;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.home_activity);
		
		mLayoutInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		
		final DisplayMetrics displayMetrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        final int width = displayMetrics.widthPixels;
		
        int screenshotWidth = (width - 4) - getResources().getDimensionPixelSize(R.dimen.latest_movie_cover_width);
        
		mLatestMoviesCoverFetcher = new ImageFetcher(this, getResources().getDimensionPixelSize(R.dimen.latest_movie_cover_width), 
													getResources().getDimensionPixelSize(R.dimen.latest_movie_cover_height));
		mLatestMoviesCoverFetcher.addImageCache(getSupportFragmentManager(), new ImageCacheParams(this, CACHE_DIR_LATEST_MOVIES_COVER));
		
		mLatestMoviesScreenshotFetcher = new ImageFetcher(this, screenshotWidth, getResources().getDimensionPixelSize(R.dimen.latest_movie_cover_height));
		mLatestMoviesScreenshotFetcher.addImageCache(getSupportFragmentManager(), new ImageCacheParams(this, CACHE_DIR_LATEST_MOVIES_SCREENSHOT));
	
		mTopRatedMoviesCoverFetcher = new ImageFetcher(this, getResources().getDimensionPixelSize(R.dimen.top_rated_movie_cover_width), 
														getResources().getDimensionPixelSize(R.dimen.top_rated_movie_cover_height));
		mTopRatedMoviesCoverFetcher.addImageCache(getSupportFragmentManager(), new ImageCacheParams(this, CACHE_DIR_LATEST_TOP_MOVIES_COVER));
		
		RelativeLayout  browseMovies = (RelativeLayout) findViewById(R.id.browse_movies);
		browseMovies.setOnClickListener(this);
		RelativeLayout  browseCelebs = (RelativeLayout) findViewById(R.id.browse_celebs);
		browseCelebs.setOnClickListener(this);
		
		mLatestMoviesAdapter = new LatestMoviesAdapter(getSupportFragmentManager());
		mTopRatedMoviesAdapter = new TopRatedMoviesAdapter();
		
		mLatestMoviesPager = (ViewPager) findViewById(R.id.pager);
		mLatestMoviesPager.setAdapter(mLatestMoviesAdapter);
		
		mViewPagerTimeThread = new ViewPagerTimeThread();
		
		mLatestMoviesPageIndicator = (CirclePageIndicator)findViewById(R.id.indicator);
		mLatestMoviesPageIndicator.setViewPager(mLatestMoviesPager);
		
		HorizontalListView topRatedMoviesListview = (HorizontalListView) findViewById(R.id.top_rated_movies_listview);
		topRatedMoviesListview.setAdapter(mTopRatedMoviesAdapter);
		topRatedMoviesListview.setOnItemClickListener(this);
		
		mAmmWebService = AmmWebService.getInstance(this);
		
		mAmmWebService.getLatestMovies(new BasicAsyncCallback() {

			public void onComplete(final WebserviceObject[] result, final Object state) {
				
				Movie[] movies = (Movie[]) result;

				if ((movies != null)) {
																									
					for (int i = 0; i < movies.length; i++) {
						
						final Movie movie = (Movie) (movies[i]);
						
						runOnUiThread(new Runnable() {public void run() { mLatestMoviesAdapter.add(movie); }});
						
						mLatestMoviesViewPagerCount++;
						
					}
					
					mViewPagerTimeThread.start();
				} 
			}

			public void onHttpClientException(final HttpClientException e, final Object state) {
				Log.w("AMM HttpClientException:", e.getMessage());
			}
			
			public void onIOException(final IOException e, final Object state) {
				Log.w("AMM IOException:", e.getMessage());
			}

			public void onWebServiceException(final WebServiceException e, final Object state) {
				Log.w("AMM WebServiceException:", e.getMessage());
				toastMessage(e.getMessage());
			}

		}, null);
		
		mAmmWebService.getTopRatedMovies(new BasicAsyncCallback() {

			public void onComplete(final WebserviceObject[] result, final Object state) {
				
				Movie[] movies = (Movie[]) result;

				if ((movies != null)) {
																									
					for (int i = 0; i < movies.length; i++) {
						
						final Movie movie = (Movie) (movies[i]);
						
						runOnUiThread(new Runnable() {public void run() { mTopRatedMoviesAdapter.add(movie); }});
						
					}
				} 
			}

			public void onHttpClientException(final HttpClientException e, final Object state) {
				Log.w("AMM HttpClientException:", e.getMessage());
			}
			
			public void onIOException(final IOException e, final Object state) {
				Log.w("AMM IOException:", e.getMessage());
			}

			public void onWebServiceException(final WebServiceException e, final Object state) {
				Log.w("AMM WebServiceException:", e.getMessage());
				toastMessage(e.getMessage());
			}

		}, null);
		
	}

	@Override
    public void onResume() {
        super.onResume();
        
        mTopRatedMoviesCoverFetcher.setExitTasksEarly(false);
        mTopRatedMoviesAdapter.notifyDataSetChanged();
        
        mLatestMoviesCoverFetcher.setExitTasksEarly(false);
        
        mLatestMoviesScreenshotFetcher.setExitTasksEarly(false);
        
        mViewPagerTimeThread.resumeThread();
    }

    @Override
    public void onPause() {
        super.onPause();
        
        mTopRatedMoviesCoverFetcher.setPauseWork(false);
        mTopRatedMoviesCoverFetcher.setExitTasksEarly(true);
        mTopRatedMoviesCoverFetcher.flushCache();
        
        mLatestMoviesCoverFetcher.setExitTasksEarly(true);
        mLatestMoviesCoverFetcher.flushCache();
        
        mLatestMoviesScreenshotFetcher.setExitTasksEarly(true);
        mLatestMoviesScreenshotFetcher.flushCache();
        
        mViewPagerTimeThread.pauseThread();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        
        mTopRatedMoviesCoverFetcher.closeCache();
        
        mLatestMoviesCoverFetcher.closeCache();
        
        mLatestMoviesScreenshotFetcher.closeCache();
        
        mViewPagerTimeThread.stopRunning();
    }
	
	@Override
	public void onClick(View view) {

		switch (view.getId()) {
			case R.id.browse_movies:
				startActivity(new Intent(this, MovieListActivity.class));
				break;
			case R.id.browse_celebs:
				startActivity(new Intent(this, CelebListActivity.class));
		}
		
	}
	
	@Override
	public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
		switch (parent.getId()) {
		case R.id.top_rated_movies_listview:
			final Intent intent = new Intent(this, MovieDetailActivity.class);
    		intent.putExtra(MovieDetailActivity.EXTRA_MOVIE_ID, (int) id);
            startActivity(intent);
			break;
	}
		
	}
	
    public ImageFetcher getLatestMoviesCoverFetcher() {
        return mLatestMoviesCoverFetcher;
    }
    
    public ImageFetcher getLatestMoviesScreenshotFetcher() {
        return mLatestMoviesScreenshotFetcher;
    }
	
	public class LatestMoviesAdapter extends FragmentPagerAdapter {
		
		private Vector<Movie> mListElements = new Vector<Movie>();
		
        public LatestMoviesAdapter(FragmentManager fm) {
            super(fm);
        }

        public int getCount() {
        	if (mListElements.isEmpty()) {
    			return 0;
    		} else {
    			return mListElements.size();
    		}
        }

        public Fragment getItem(int position) {
        	Movie movie = (Movie) mListElements.elementAt(position);
        	return LatestMoviesFragment.newInstance(movie.getId(), movie.getCover(), movie.getMobileScreenshot());
        }
        
        public void add(Movie data) {
        	mListElements.addElement(data);
            notifyDataSetChanged();
        }
    }

	
	public class TopRatedMoviesAdapter extends BaseAdapter {

		private Vector<Movie> mListElements = new Vector<Movie>();
		
		private class ViewHolder {
		    public ImageView mMovieCover;
		}
		
        public TopRatedMoviesAdapter() {
        }

        public int getCount() {
        	if (mListElements.isEmpty()) {
    			return 0;
    		} else {
    			return mListElements.size();
    		}
        }

        public Object getItem(int position) {
        	Movie movie = (Movie) mListElements.elementAt(position);
        	return movie;
        }

        public long getItemId(int position) {
        	Movie movie = (Movie) mListElements.elementAt(position);
    		return movie.getId();
        }

        public View getView(int position, View convertView, ViewGroup parent) {

        	ViewHolder holder;

        	Movie movie = (Movie) mListElements.elementAt(position);
        	
        	View movieRow = convertView;
        	
        	if (movieRow == null) {
        		movieRow = mLayoutInflater.inflate(R.layout.top_rated_movie_listview_row, parent, false);
        		holder  = new ViewHolder();
        		holder.mMovieCover = (ImageView) movieRow.findViewById(R.id.movie_cover);
        		
        		movieRow.setTag(holder);
        	}else{
        		holder = (ViewHolder) movieRow.getTag();
        	}

        	mTopRatedMoviesCoverFetcher.loadImage(movie.getCover(), holder.mMovieCover);
  
        	return movieRow;
        }
        
        public void add(Movie data) {
        	mListElements.addElement(data);
            notifyDataSetChanged();
        }

    }
	
	
	private class ViewPagerTimeThread extends Thread {
	
		private boolean mKeepRunning;
		private boolean mPaused;
		
		public ViewPagerTimeThread() {
			mKeepRunning = true;
			mPaused = false;
		}
		
		public void run()
	    {
	    	
	    	while( mKeepRunning )
	        {
	            try
	            {
	                synchronized( this )
	                {
	                	//wait for 10 seconds before running the thread
	                	wait( 1000 * 10 );
	                }
	            }
	            catch( final InterruptedException e )
	            {
	                e.printStackTrace();
	                return;
	            }
	            
	            //if the thread has been paused, then don't update the view pager
	            if(!mPaused){
	            	runOnUiThread(new Runnable() {public void run() { 
		    			
		            	//if not the end of the page, then go to the next page, else go to back to page 1
			            if(mLatestMoviesViewPagerCount != mLatestMoviesPager.getCurrentItem()){
			            	mLatestMoviesPager.setCurrentItem(mLatestMoviesPager.getCurrentItem() + 1);
			            }else{
			            	mLatestMoviesPager.setCurrentItem(0);
			            } 
		            
		            }});
	            }        
	        }
	    }
		
		/**
	     * Stops the view page animation.
	     */
	    public void pauseThread()
	    {
	        synchronized( this )
	        {
	        	mPaused = true;
	            notifyAll();
	        }
	    }
	    
	    /**
	     * Resume the view page animation.
	     */
	    public void resumeThread()
	    {
	        synchronized( this )
	        {
	        	mPaused = false;
	            notifyAll();
	        }
	    }
		
		/**
	     * Stops the thread from continuing its processing.
	     */
	    public void stopRunning()
	    {
	        synchronized( this )
	        {
	        	mKeepRunning = false;
	            notifyAll();
	        }
	    }
		
	}
	
}
